리포트를 작성할 때 그래프를 이용한 시각화는 매우 필수적이다. 이는 전체적인 결과를 시각화하여 남에게 보여줄 때만 유용한 것이 아니라, 직접 분석을 진행하는 엔지니어들에게도 매우 중요한 도구이다. 왜냐하면 데이터를 숫자로 하나 하나 파악하는 것 보다 어떨 때는 시각적으로 데이터의 구조를 파악할 수 있다면 의사 결정을 더 빠르게 내릴 수 있기 때문이다.

MATLAB에서는 2차원 그래프를 그릴 수 있도록 도와주는 내장함수가 많이 있다. 이번 페이지에서는 대표적인 2차원 그래프 함수들에 대해 알아보고자 한다.

plot

“plot”(플롯 혹은 플랏이라고 읽음)은 가장 기본적인 2차원 그래프라고 할 수 있다. 그래프 그리기는 초등학교 과정에 포함되어 있을 만큼 기본적인 도구라고 할 수 있다. “plot” 함수를 다루면서 “plot” 함수의 여러가지 옵션들과 함께 사용하면 유용한 함수들을 차근히 익혀보도록 하자. 이 옵션들은 다른 함수에서도 유사하게 사용될 수 있으므로 유용할 수 있다.

plot 기본 구문

“plot” 함수의 기본 구문은 아래와 같다.

plot(y)

여기서 y는 벡터 혹은 행렬을 삽입할 수 있는데, 설명의 편의를 위해 벡터만 생각해보도록 하자. plot에 하나의 벡터를 넣는 경우는 아래와 같이 y 값(높이)만 생각하는 경우라고 할 수 있다.


새 스크립트(New Script)를 만들고 아래의 코드를 직접 실행시켜보자.

plot([1, 4, 2, 3])


위 그림을 보면 1, 4, 2, 3 이라는 y 값(높이)들이 차례대로 나열되어 있는 것을 알 수 있다. 또한, x 축의 값은 자동으로 1, 2, 3, 4에 대응된 것을 볼 수 있다. 이것은 벡터 [1, 4, 2, 3] 의 순서가 기재된 것이다.

x, y 축 모두 변수 대응시키기

그렇다면 만약 x축에 1, 2, 3, 4 대신에 11, 12, 13, 14를 대응시키고 싶다면 어떻게 하면 좋을까? plot 함수에 x, y 두 개를 모두 입력하면 된다.


x = [11, 12, 13, 14];
y = [1, 4, 2, 3];
plot(x, y)


하나 중요한 점은 x와 y에 해당하는 벡터의 원소 순서가 아주 중요하다는 점이다. 위 그림에서는 (11, 1), (12, 4), (13, 2), (14, 3)의 네 개 좌표의 점들을 순서대로 연결했다는 점을 잘 생각해보자. x에 들어간 값들의 순서를 직접 바꿔 넣어보면서 어떤 결과가 도출되는지 직접 확인해보자.

또 하나 다른 중요한 부분은 연결하려고 하는 점들의 x 좌표들을 하나의 벡터에 몰아넣고, y 좌표들을 하나의 벡터에 몰아넣어야 한다는 점이다. 이 부분이 아주 헷갈릴 수 있기 때문에 아래의 오각형 그림을 “plot” 함수로 그릴 때 어떻게 그려야할지 잘 생각해보자.


두 가지 포인트를 잘 기억해야 한다. 좌표의 순서쌍을 잘 지켜야한다는 점과 x, y 좌표들을 서로 다른 두 벡터에 각각 몰아 넣어야 한다는 점이다.

x = [1.0, 0.0, 0.4, 1.6, 2.0, 1.0];
y = [2.0, 1.3, 0.2, 0.2, 1.3, 2.0];
plot(x, y)


좌표 순서쌍의 순서를 바꾸면 아래와 같은 별 모양으로 바꿔볼 수도 있다.


x = [1.0, 0.4, 2.0, 0.0, 1.6, 1.0];
y = [2.0, 0.2, 1.3, 1.3, 0.2, 2.0];
plot(x, y)


LineSpec 활용하기

그런데, 또 생각해보니 지금까지 그린 그래프에서는 y(1), y(2), y(3), y(4) 의 값들이 선으로만 연결되어 있어서 이 값들이 정확히 어디있는지 파악하기 어렵다. 이럴 때는 LineSpec 옵션을 활용하면 된다. LineSpec 옵션을 사용하기 위해선 아래와 같은 구문을 사용할 수 있다. 여기서 ‘o-‘는 동그라미 마커와 실선을 동시에 활용하라는 의미이다. 이는 ‘-o’와 같이 순서가 바뀌어도 상관없다.

x = [11, 12, 13, 14];
y = [1, 4, 2, 3];
plot(x, y, 'o-')


추가로 “-“과 같은 선의 스타일에 관한 LineSpec 옵션은 “선 스타일(linestyle)”이라고도 부른다. 또, “o”과 같은 형태의 꼭지점 형식에 관한 LineSpec 옵션은 “마커(marker)”라고 부른다. LineSpec 옵션에는 색깔도 포함되어 있다. 만약, 선의 색깔을 빨간색으로 바꾸고 싶다면 아래와 같이 코드를 수정해주면 된다. “r”은 “red”를 줄여서 쓴 말이다. 마찬가지로 “r”, “o”, “-“ 등의 LineSpec 옵션 문자들은 순서가 뒤바뀌어도 관계없다.

x = [11, 12, 13, 14];
y = [1, 4, 2, 3];
plot(x, y, 'ro-')


더 다양한 LineSpec 옵션에 관해서는 아래 그림의 MathWorks 홈페이지에서 확인할 수 있다.

x, y 축 범위 조정하기

이번에는 x 축의 값이 정수로 떨어지지 않는 0, $\pi/2$, $\pi$, $3\pi/2$, $2\pi$인 경우를 생각해 “plot”을 수행해보자.

x = [0, pi/2, pi, 3*pi/2, 2*pi];
y = [1, 4, 2, 3, 2];
plot(x, y, 'o-')


위 결과를 보면 오른쪽 끝에 빈 공간이 생기는 것을 알 수 있으며 이것이 보기 좋지 않을 수 있다. 이것을 수정하기 위해 “xlim” 함수를 이용해 그래프의 x 축의 표현 범위를 조정해보자. xlim에는 왼쪽 한계 범위와 오른쪽 한계 범위를 원소로 하는 벡터를 입력해주면 된다.

x = [0, pi/2, pi, 3*pi/2, 2*pi];
y = [1, 4, 2, 3, 2];
plot(x, y, 'o-')
xlim([0, 2*pi]);


마찬가지 방식으로 “ylim” 함수를 사용할 수 있다. ylim에는 아랫쪽 한계 범위와 윗쪽 한계 범위를 원소로 하는 벡터를 입력해주면 된다. 가령 이런식이다.

x = [0, pi/2, pi, 3*pi/2, 2*pi];
y = [1, 4, 2, 3, 2];
plot(x, y, 'o-')
xlim([0, 2*pi]);
ylim([0, 5]);


x, y 축 눈금값과 레이블 지정하기

지금까지 그린 그래프를 보면 눈금이 1, 2, 3과 같이 1단위로 그려져 있는 것을 알 수 있다. 이런 경우에는 0, pi/2, pi와 같이 pi/2 단위로 그리면 그래프를 더 쉽게 이해할 수 있을 것이다. 이런 경우 “xticks” 함수와 “xticklabels” 함수를 이용할 수 있다. “xticks”는 눈금을 조정하고 “xticklabels”는 눈금에 표시되는 레이블을 조정한다.


우리는 “xticks” 함수로 눈금을 $\begin{bmatrix}0, \pi/2, \pi, 3\pi/2, 2\pi \end{bmatrix}$에 오도록 조정하고, 눈금 레이블도 그리스 문자 $\pi$를 이용하도록 조정해보자.

x = [0, pi/2, pi, 3*pi/2, 2*pi];
y = [1, 4, 2, 3, 2];
plot(x, y, 'o-')
xlim([0, 2*pi]);
ylim([0, 5]);
xticks([0, pi/2, pi, 3*pi/2, 2*pi])
xticklabels({'0','\pi/2', '\pi','3\pi/2', '2\pi'})


추가 옵션 이용하기

plot 함수를 사용할 때 앞서 본 마커 모양, 선 색깔, 선 스타일은 LineSpec이라 하여 약어를 이용해 편하게 사용할 수 있도록 설계되어 있지만 이 외에도 아래와 같은 옵션을 Name-Value 쌍 형식으로 지정할 수 있다.

  • Color: 선 색 (e.g., “r” 혹은 “red” 혹은 [1, 0, 0] 등)
  • Line Style: 선 스타일 (e.g., “-“, “–”, “:”, “-.”, “none”)
  • LineWidth: 선 너비 (디폴트: 0.5, 양의 값)
  • Marker: 마커 기호 (“none”, “o”, “+”, “^”, “.”, 등)
  • MarkerIndices: 마커를 표시할 데이터 인덱스 (양의 정수로 구성된 벡터)
  • MarkerEdgeColor: 마커 윤곽선 색 (“none”, “auto”, “r”, [1, 0, 0] 등)
  • MarkerFaceColor: 마커 채우기 색 (“none”, “auto”, “r”, [1, 0, 0] 등)
  • MarkerSize: 마커 크기 (디폴트: 6, 양의 값)

이 추가 옵션들은 아래와 같은 문법으로 지정할 수 있다. 참고로 코드 중간에 들어간 줄임말(“…”) 은 스크립트가 너무 길 때 한 줄 넘겨서 계속 입력하게 해주는 명령어이다.

plot(x, y, color = 'r' , LineStyle = '--', LineWidth = 2, Marker = 'o', ...
  MarkerIndices = [1, 3, 4, 5] , MarkerEdgecolor = 'r', MarkerFaceColor = 'k', MarkerSize = 10)

혹은 아래와 같은 따옴표 쌍 방식도 가능하다. R2021a 이전 버전에서는 아래의 따옴표 쌍 방식만 허용된다. (옵션명의 대소문자는 구분하지 않아도 된다.)

plot(x, y, 'color', 'r', 'linestyle', '--', 'linewidth', 0.5, 'marker', 'o', ...
  'markerindices', [1, 3, 4, 5], 'markeredgecolor', 'r',' markerfacecolor','k', 'markersize', 10)

아래의 예시를 확인해보자.

x = [0, pi/2, pi, 3*pi/2, 2*pi];
y = [1, 4, 2, 3, 2];
plot(x, y, color = 'r' , LineStyle = '--', LineWidth = 2, Marker = 'o', ...
  MarkerIndices = [1,3,4,5] , MarkerEdgecolor = 'r', MarkerFaceColor = 'k', MarkerSize = 10)
xlim([0, 2*pi]);
xticks(0:pi/2:2*pi)
xticklabels({'0','\pi/2', '\pi','3\pi/2', '2\pi'})


타이틀, x, y축 라벨 텍스트 넣기

함수 “title”, “xlabel”, “ylabel”을 이용하면 타이틀, x, y 축에 라벨 텍스트를 넣을 수 있다. 참고로 이 세 개의 함수들은 LaTeX를 지원하므로 수식 작성이 필요한 경우 두 “$$” 사이에 라텍스 문법을 이용해 문구를 작성하고 ‘interpreter’ 옵션을 ‘latex’로 설정하면 된다.

x = [0, pi/2, pi, 3*pi/2, 2*pi];
y = [1, 4, 2, 3, 2];
plot(x, y, 'o-')
title("my plot");
xlabel("x");
ylabel("$$a^2+b^2+c$$",'interpreter','latex')


눈금 선(grid) 넣기

함수 “grid” 를 이용하면 눈금 선을 넣을 수 있다. 주 눈금 선과 함께 보조 눈금 선을 함께 넣고 싶은 경우 “minor” 옵션을 함께 이용하면 된다. 아래의 예시를 살펴보자.

x = [0, pi/2, pi, 3*pi/2, 2*pi];
y = [1, 4, 2, 3, 2];

figure;
plot(x, y);
grid on;

figure;
plot(x, y);
grid on;
grid minor % 보조 눈금선 까지 넣는 경우


두 개 이상의 그래프를 겹쳐 그려주기

두 개 이상의 그래프를 그려주기 위해서는 “hold” 함수를 이용할 수 있다. “hold on” 이라고 하면 새로운 그래프를 plot 할 때 원래의 그래프에 겹쳐서 그려주기 되고, “hold off” 라고 명령해주면 새로운 그래프가 그려질 때 원래의 그래프는 없어진다. 아래의 예시를 살펴보자.

x = linspace(0, 2*pi, 100);
y1 = sin(x);
y2 = cos(x);

figure;
plot(x, y1);
hold on;
plot(x, y2);


범례(legend) 넣기

함수 “legend”를 이용하면 범례(legend)를 넣을 수 있다. 아래의 예시를 살펴보자.

x = linspace(0, 2*pi, 100);
y1 = sin(x);
y2 = cos(x);

figure;
plot(x, y1);
hold on;
plot(x, y2);
legend('sin(x)', 'cos(x)')


한 figure 창에 두 개의 그래프 함께 그려주기

“subplot” 함수를 이용하면 한 figure 창에 두 개의 그래프를 동시에 그려줄 수 있다. “subplot”의 구문은 subplot(m,n,p)와 같은데 figure를 m행 n열의 형태로 나눠주고 p 번째 위치의 좌표축에 그래프를 그려주겠다는 의미이다. 아래의 그림을 보면 더 시각적으로 이해할 수 있을 것으로 생각한다.


아래의 예시를 보자.

x = linspace(0, 2*pi, 100);
y1 = sin(x);
y2 = cos(x);

figure;
subplot(1,2,1);
plot(x, y1);
subplot(1,2,2);
plot(x, y2);


위 그림은 figure 창의 크기를 마우스로 늘려준 것이다.

subplot을 잘 이용하면 2행, 2열의 구성으로 subplot들을 구성하되, 3, 4번 subplot 위치에 하나의 그래프를 다 넣어줄 수도 있다. 가령, 아래와 같은 형식으로 꾸밀 수 있다는 의미이다.


아래의 예시를 살펴보자.

x = linspace(0, 2*pi, 100);
y1 = sin(x);
y2 = cos(x);

figure;
subplot(2,2,1);
plot(x, y1);
subplot(2,2,2);
plot(x, y2);
subplot(2,2,[3, 4]);
plot(x, y1);
hold on;
plot(x, y2);
axis tight % 빈 틈 없이 그래프를 구성하도록 하는 명령어


축(axis) 스타일 지정하기

“axis” 함수를 이용하면 축(axis) 스타일을 설정할 수 있다. 전체 style 리스트는 아래 그림의 MathWorks 홈페이지에서 확인할 수 있지만, 주로 사용하는 것은 “tight”, “square” 옵션 두 가지 인 것 같아 이 두 가지만 소개하고자 한다.

“tight” 옵션을 이용하면 그래프 표현 시 빈 공간 없이 그려지게 된다. 아래의 예시를 보면 바로 이해할 수 있다.

x = linspace(0, 2*pi, 100);
y1 = sin(x);

figure;
plot(x, y1);
title('no axis style applied')

figure;
plot(x, y1);
title('axis tight');
axis tight


또 하나 소개하고자 하는 옵션은 “equal” 옵션으로 x, y 축의 길이를 동일하게 만들어준다. 이 옵션은 원을 그렸을 때 그려진 원이 찌그러지지 않게 하는 경우에 자주 사용한다.

theta = linspace(0, 2*pi, 100);
x = cos(theta);
y = sin(theta);
figure;
plot(x, y);
title('no axis style applied');

figure;
plot(x, y);
axis equal
title('axis equal');


imagesc

imagesc는 행렬을 시각화 하고 싶은 경우 사용할 수 있다. 이것이 무슨 말인지 더 자세하게 설명하기 위해 아래와 같은 행렬을 생각해보자.

\[A = \begin{bmatrix}1 & 2 \\\\ 3 & 4\end{bmatrix}\]

각 1, 2, 3, 4 의 값에 해당하는 색깔들을 미리 정해둔다면 아래와 같이 시각화 할 수 있을 것이다.


A = [1,2; 3,4];
imagesc(A); colormap(parula); colorbar;

굳이 왜 이런 방식을 사용해서 행렬을 시각화해야하나 싶기도 하겠지만 더 크고 복잡한 행렬들은 간혹 시각화해서 보여주면 의미가 바로 드러나기도 한다. 아래와 같은 예시를 살펴보자.

C = gallery('circul',11);
imagesc(C)
axis square
colorbar


scatter

산점도(scatter) 플롯을 그려주는 함수이다. 사실상 “plot” 함수를 사용하고 마커의 모양을 ‘o’로 하는 것과 결과상에 큰 차이는 없다. 아래의 예시를 확인해보자.

x = linspace(0,3*pi,200);
y = cos(x) + rand(1,200);  

figure;
subplot(2, 1, 1);
plot(x, y, 'o');
title('using plot');
subplot(2, 1, 2);
scatter(x,y)
title('using scatter')


그런데, “plot” 함수는 한 그래프 전체에 동일한 속성이 걸리는 반면, “scatter” 함수는 각 점들에 대해 속성을 지정할 수 있다는 점에서 차이가 있다.

“scatter” 함수의 문법은 아래와 같다.

scatter(x, y, sz, c) % 여기서 sz는 마커 사이즈, c는 색깔이다.

가령 100개 데이터 포인트가 있다고 했을 때, 첫 번 째 데이터 포인트의 크기는 1, 두 번째 데이터 포인트의 크기는 2 등이라고 하면 sz에는 1:100이라는 벡터를 삽입하면 되는 것이다. 색깔도 마찬가지로 첫 번째 데이터 포인트의 색깔은 RGB로 [1, 0, 0], 두 번째 데이터 포인트의 색깔은 RGB로 [0, 1, 0] 과 같이 설정해줄 수 있는 것이다. 아래의 예시를 확인해보자.

x = linspace(0,3*pi,200);
y = cos(x) + rand(1,200);  

figure;
subplot(2, 1, 1);
scatter(x,y,linspace(5, 50, 200))
subplot(2, 1, 2);
scatter(x, y, [], parula(200), "filled") % filled 옵션은 색깔을 Marker에 채워 넣어 달라는 의미이다.


참고로 위의 예시에서 “parula(200)” 이라고 입력한 것은 Parula 컬러맵의 색깔을 200개로 쪼갠 컬러맵 행렬을 얻기 위해 사용하였다. 컬러에 관한 더 자세한 내용은 “색상, 폰트, 수식” 편에서 다룬다.

histogram

가장 자주 사용하는 2D 그래프 중 하나는 히스토그램(histogram)이라고 생각한다. 히스토그램은 데이터의 전체 분포를 확인하는데 유용하다.

“histogram”의 기본 구문은 아래와 같다.

histogram(x)

예를 들면 아래와 같이 수행해볼 수 있다.

x = randn(1000, 1);
histogram(x);


“histogram” 함수를 사용할 때 가장 많이 썼던 옵션은 “nbins”로 아래와 같이 bin 개수를 수정해주는 옵션이다. “nbins” 옵션은 histogram의 두 번째 입력으로 넣어주면 된다.

x = randn(1000, 1);

figure;
subplot(2,2,1);
histogram(x, 10);
title('nbins = 10')
subplot(2,2,2);
histogram(x, 20);
title('nbins = 20')
subplot(2,2,3);
histogram(x, 30);
title('nbins = 30')
subplot(2,2,4);
histogram(x, 40);
title('nbins = 40')


polarplot

간혹 극좌표에 그림을 그려야 할 때도 있는데, MATLAB에서는 “polarplot” 기능을 이용하면 편하다. 여기서는 간단한 예시만 보여주고자 한다. “polarplot”의 기타 옵션들은 “plot”과 거의 유사하다.

theta = linspace(0, 2*pi, 1000);
r = sin(2*theta) .* cos(2*theta);
polarplot(theta, r)